using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Logging;
using Volo.Abp;
using Volo.Abp.Caching;
using Volo.Abp.Domain.Services;
using Volo.Abp.Identity;
using Volo.Abp.Uow;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Domain.Entities;
using UserManagementService.Users;

namespace UserManagementService.Permissions;

/// <summary>
/// 用户权限服务实现
/// </summary>
public class UserPermissionService : DomainService, IUserPermissionService
{
    private readonly IIdentityUserRepository _userRepository;
    private readonly IIdentityRoleRepository _roleRepository;
    private readonly IDistributedCache<UserPermissionCacheItem> _cache;
    private readonly ILogger<UserPermissionService> _logger;

    public UserPermissionService(
        IIdentityUserRepository userRepository,
        IIdentityRoleRepository roleRepository,
        IDistributedCache<UserPermissionCacheItem> cache,
        ILogger<UserPermissionService> logger)
    {
        _userRepository = userRepository;
        _roleRepository = roleRepository;
        _cache = cache;
        _logger = logger;
    }

    public async Task<List<string>> GetUserPermissionsAsync(Guid userId, CancellationToken cancellationToken = default)
    {
        var cacheKey = GetUserPermissionCacheKey(userId);
        var cachedItem = await _cache.GetAsync(cacheKey, token: cancellationToken);

        if (cachedItem != null)
        {
            return cachedItem.Permissions;
        }

        var user = await _userRepository.GetAsync(userId, cancellationToken: cancellationToken);
        if (user == null)
        {
            throw new EntityNotFoundException(typeof(IdentityUser), userId);
        }

        var permissions = new List<string>();

        // 获取用户角色权限
        var rolePermissions = await GetUserRolePermissionsAsync(userId, cancellationToken);
        permissions.AddRange(rolePermissions);

        // 获取用户直接权限
        var directPermissions = await GetUserDirectPermissionsAsync(userId, cancellationToken);
        permissions.AddRange(directPermissions);

        var uniquePermissions = permissions.Distinct().ToList();

        // 缓存结果
        await _cache.SetAsync(
            cacheKey,
            new UserPermissionCacheItem { Permissions = uniquePermissions },
            new DistributedCacheEntryOptions
            {
                AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(30)
            },
            token: cancellationToken);

        return uniquePermissions;
    }

    public async Task<bool> HasPermissionAsync(Guid userId, string permissionName, CancellationToken cancellationToken = default)
    {
        var permissions = await GetUserPermissionsAsync(userId, cancellationToken);
        return permissions.Contains(permissionName) || permissions.Contains("*");
    }

    public async Task<bool> HasAnyPermissionAsync(Guid userId, params string[] permissionNames)
    {
        if (permissionNames == null || permissionNames.Length == 0)
        {
            return false;
        }

        var permissions = await GetUserPermissionsAsync(userId);
        return permissionNames.Any(p => permissions.Contains(p) || permissions.Contains("*"));
    }

    public async Task<bool> HasAllPermissionsAsync(Guid userId, params string[] permissionNames)
    {
        if (permissionNames == null || permissionNames.Length == 0)
        {
            return true;
        }

        var permissions = await GetUserPermissionsAsync(userId);
        return permissionNames.All(p => permissions.Contains(p) || permissions.Contains("*"));
    }

    public async Task GrantPermissionAsync(Guid userId, string permissionName, string? grantedBy = null, CancellationToken cancellationToken = default)
    {
        _logger.LogInformation("授予用户权限: UserId={UserId}, Permission={Permission}, GrantedBy={GrantedBy}",
            userId, permissionName, grantedBy);

        // 这里应该实现权限授予逻辑
        // 由于ABP Identity已经有权限管理，这里可以集成或扩展

        await RefreshUserPermissionCacheAsync(userId, cancellationToken);

        // 添加权限变更历史
        // TODO: 实现权限历史记录
    }

    public async Task GrantPermissionsAsync(Guid userId, List<string> permissionNames, string? grantedBy = null, CancellationToken cancellationToken = default)
    {
        _logger.LogInformation("批量授予用户权限: UserId={UserId}, Count={Count}, GrantedBy={GrantedBy}",
            userId, permissionNames.Count, grantedBy);

        foreach (var permissionName in permissionNames)
        {
            await GrantPermissionAsync(userId, permissionName, grantedBy, cancellationToken);
        }
    }

    public async Task RevokePermissionAsync(Guid userId, string permissionName, string? revokedBy = null, CancellationToken cancellationToken = default)
    {
        _logger.LogInformation("撤销用户权限: UserId={UserId}, Permission={Permission}, RevokedBy={RevokedBy}",
            userId, permissionName, revokedBy);

        // 这里应该实现权限撤销逻辑

        await RefreshUserPermissionCacheAsync(userId, cancellationToken);

        // 添加权限变更历史
        // TODO: 实现权限历史记录
    }

    public async Task RevokePermissionsAsync(Guid userId, List<string> permissionNames, string? revokedBy = null, CancellationToken cancellationToken = default)
    {
        _logger.LogInformation("批量撤销用户权限: UserId={UserId}, Count={Count}, RevokedBy={RevokedBy}",
            userId, permissionNames.Count, revokedBy);

        foreach (var permissionName in permissionNames)
        {
            await RevokePermissionAsync(userId, permissionName, revokedBy, cancellationToken);
        }
    }

    public async Task<List<UserPermissionHistoryDto>> GetPermissionHistoryAsync(Guid userId, DateTime? startTime = null, DateTime? endTime = null, CancellationToken cancellationToken = default)
    {
        // TODO: 实现权限历史查询
        return new List<UserPermissionHistoryDto>();
    }

    public async Task<List<Guid>> GetUsersWithPermissionAsync(string permissionName, CancellationToken cancellationToken = default)
    {
        // TODO: 实现权限用户查询
        return new List<Guid>();
    }

    public async Task<List<string>> GetUserRolePermissionsAsync(Guid userId, CancellationToken cancellationToken = default)
    {
        var user = await _userRepository.GetAsync(userId, includeDetails: true, cancellationToken: cancellationToken);
        if (user == null)
        {
            return new List<string>();
        }

        var rolePermissions = new List<string>();

        foreach (var role in user.Roles)
        {
            var roleEntity = await _roleRepository.GetAsync(role.RoleId, cancellationToken: cancellationToken);
            if (roleEntity != null)
            {
                // ABP Identity的角色权限管理可能需要使用其他方式获取
                // 这里简化实现，实际应该根据ABP的权限系统获取角色权限
                // rolePermissions.AddRange(roleEntity.GetPermissions());
            }
        }

        return rolePermissions.Distinct().ToList();
    }

    public async Task<List<string>> GetUserDirectPermissionsAsync(Guid userId, CancellationToken cancellationToken = default)
    {
        // TODO: 实现用户直接权限查询
        return new List<string>();
    }

    public async Task RefreshUserPermissionCacheAsync(Guid userId, CancellationToken cancellationToken = default)
    {
        var cacheKey = GetUserPermissionCacheKey(userId);
        await _cache.RemoveAsync(cacheKey, token: cancellationToken);

        _logger.LogDebug("已刷新用户权限缓存: UserId={UserId}", userId);
    }

    private static string GetUserPermissionCacheKey(Guid userId)
    {
        return $"UserPermission:{userId}";
    }
}

/// <summary>
/// 用户权限缓存项
/// </summary>
public class UserPermissionCacheItem
{
    public List<string> Permissions { get; set; } = new();
}